﻿using System;
using System.Collections.Generic;
using BinarySerialization;

namespace EditMode
{
    /// <summary>
    /// Edit camera orbit modes.
    /// </summary>
    public enum CameraOrbit : byte
    {
        標準 = 0x00,
        直線 = 0x01,
        曲線 = 0x02,
    }

    /// <summary>
    /// Player focus points.
    /// </summary>
    public enum PlayerFocus : ushort
    {
        なし = 0x000100,
        P1_顔 = 0x0005,
        P1_胸 = 0x0085,
        P1_腰 = 0x0105,
        P2_顔_0 = 0x0015,
        P2_顔_1 = 0x0017,
        P2_胸 = 0x0095,
        P2_腰 = 0x0115,
        P3_顔 = 0x0025,
        P3_胸 = 0x00A5,
        P3_腰 = 0x0125,
    }

    /// <summary> 
    /// Edit camera instruction.
    /// </summary> 
    [Serializable]
    public class EditCamera
    {
        #region Properties
        [FieldOrder(0)]
        public uint Time { get; set; }

        [FieldOrder(1)]
        public byte ColorId { get; set; }

        [FieldOrder(2)]
        public CameraOrbit OrbitMode { get; set; }

        [FieldOrder(3)]
        public byte KeyPointCount { get; set; }

        [FieldOrder(4)]
        public byte UnknownBool { get; set; }

        [FieldOrder(5)]
        [FieldCount(nameof(KeyPointCount))]
        public List<CameraKeyPoint> CameraKeyPoints = new List<CameraKeyPoint>();
        #endregion
        #region Constructor
        public EditCamera()
        {

        }
        #endregion
        #region Methods
        /// <summary>
        /// Returns a new Edit Camera List containing the spliced camera key points.
        /// </summary>
        /// <param name="cameras"></param>
        public static List<EditCamera> SliceCamera(List<EditCamera> cameras)
        {
            // TODO: something isn't quite right here
            var newCameras = new List<EditCamera>();
            foreach (var camera in cameras)
            {
                uint newTime = camera.Time;
                foreach (var kp in camera.CameraKeyPoints)
                {
                    var newCamera = new EditCamera
                    {
                        Time = newTime,
                        ColorId = camera.ColorId,
                        OrbitMode = camera.OrbitMode,
                        KeyPointCount = 0x01,
                        UnknownBool = camera.UnknownBool
                    };
                    var newKeyPoint = new CameraKeyPoint();
                    newKeyPoint = kp;
                    newCamera.CameraKeyPoints.Add(newKeyPoint);
                    newCameras.Add(newCamera);
                    newTime += kp.CameraDuration;
                }
            }
            return newCameras;
        }
        #endregion
    }

    /// <summary> 
    /// Edit camera key point instruction. Each edit camera has to contain but is not limited to one key point.
    /// </summary> 
    [Serializable]
    public class CameraKeyPoint
    {
        [FieldOrder(0)]
        public Vector3 CameraStart { get; set; } = new Vector3();

        [FieldOrder(1)]
        public Vector3 FocusPointStart { get; set; } = new Vector3();

        [FieldOrder(2)]
        public Vector3 UnknowntStart { get; set; } = new Vector3();

        [FieldOrder(3)]
        public Vector3 CameraEnd { get; set; } = new Vector3();

        [FieldOrder(4)]
        public Vector3 FocusPointEnd { get; set; } = new Vector3();

        [FieldOrder(5)]
        public Vector3 UnknowntEnd { get; set; } = new Vector3();

        [FieldOrder(6)]
        public float CameraAccelerationStart { get; set; }

        [FieldOrder(7)]
        public float CameraAccelerationEnd { get; set; }

        [FieldOrder(8)]
        public byte Unknown1 { get; set; }

        [FieldOrder(9)]
        public PlayerFocus PlayerFocus { get; set; }

        [FieldOrder(10)]
        public byte Unknown2 { get; set; }

        [FieldOrder(11)]
        public uint CameraDuration { get; set; } = 0x02;

        public CameraKeyPoint() { }
    }
}
